package com.zhihui.online.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhihui.online.dto.menu.AssignMenuDTO;
import com.zhihui.online.entity.Menu;
import com.zhihui.online.entity.RoleMenu;
import com.zhihui.online.exception.MyCustomerException;
import com.zhihui.online.mapper.MenuMapper;
import com.zhihui.online.mapper.RoleMenuMapper;
import com.zhihui.online.service.MenuService;
import com.zhihui.online.utils.MenuHelper;
import com.zhihui.online.utils.ResultCodeEnum;
import com.zhihui.online.utils.RouterHelper;
import com.zhihui.online.vo.MenuVO;
import com.zhihui.online.vo.menu.RouterVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author 程序员阿良, 21岁纯情后爸, 懒得想名字
 * @since 2024-08-01
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    /**
     * 根据用户Id获取菜单权限
     *
     * @param userId
     * @return
     */
    @Override
    public List<RouterVo> findUserMenuList(Long userId) {
        //超级管理员admin账号id为：1819208681953292289
        // 我们约定 admin 是 超级管理员拥有所有的权限
        List<Menu> menuList = null;

        if (userId == 1819208681953292289L) {
            //a.  表示是超级管理员
            menuList = baseMapper.selectList(new QueryWrapper<Menu>().eq("status", 1).orderByAsc("sort_value"));
        } else {
            // b. 其他非超级管理员的 用户
            menuList = baseMapper.findListByUserId(userId);
        }
        // 判断集合是否为空
        if (menuList.isEmpty()) {
            throw new MyCustomerException(ResultCodeEnum.NULL_FAIL);
        }
        //转换为视图对象
        List<MenuVO> collect = menuList.stream().map(menu -> {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(menu, menuVO);
            return menuVO;
        }).collect(Collectors.toList());
        //c.构建树形数据
        List<MenuVO> sysMenuTreeList = MenuHelper.bulidTree(collect);

        // MeunHelper返回的数据属性和 前端路由的属性不一致，所以要处理
        //d.构建路由

        return RouterHelper.buildRouters(sysMenuTreeList);
    }

    /**
     * 根据用户Id获取按钮权限
     *
     * @param id
     * @return
     */
    @Override
    public List<String> findUserPermsList(Long id) {
        //超级管理员admin账号id为：1
        List<Menu> sysMenuList = null;
        if (id == 1) {
            sysMenuList = this.baseMapper.selectList(new QueryWrapper<Menu>().eq("status", 1));
        } else {
            sysMenuList = this.baseMapper.findListByUserId(id);
        }
        // 判断集合是否为空
        if (sysMenuList.isEmpty()) {
            throw new MyCustomerException(ResultCodeEnum.NULL_FAIL);
        }
        //封装按钮权限
        //先过滤数据，然后转为string集合
        return sysMenuList.stream().filter(menu -> menu.getType() == 2)
                .map(Menu::getPerms).collect(Collectors.toList());
    }

    /**
     * 加载菜单列表
     * @return
     */
    @Override
    public List<MenuVO> findNodes() {
        //1.获取所有的菜单
        List<Menu> menuList = this.baseMapper.selectList(null);
        //转换为视图对象
        List<MenuVO> collect = menuList.stream().map(menu -> {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(menu, menuVO);
            return menuVO;
        }).collect(Collectors.toList());

        //        2.所有菜单数据转换要求数据格式
        return MenuHelper.bulidTree(collect);
    }

    /**
     * 根据Id删除菜单
     * @param id
     */
    @Override
    public void removeMenuById(Long id) {
        //查询当前删除菜单下面是否子菜单
        //根据id = parentid
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", id);
        Integer count = baseMapper.selectCount(wrapper);
        if (count > 0) {//有子菜单
            throw new MyCustomerException(201, "请先删除子菜单");
        }
        //调用删除
        baseMapper.deleteById(id);
    }


    @Resource
    private RoleMenuMapper roleMenuMapper;

    /**
     * 根据角色获取菜单列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<MenuVO> findSysMenuByRoleId(Long roleId) {
        //获取所有status为1的权限列表
        List<Menu> menuList = baseMapper.selectList(new QueryWrapper<Menu>().eq("status", 1));

        //根据角色id获取角色权限
        List<RoleMenu> roleMenus = this.roleMenuMapper.selectList(new QueryWrapper<RoleMenu>().eq("role_id", roleId));
        //获取该角色已分配的所有权限id
        List<Long> roleMenuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());

        //遍历所有权限列表,设置权限是否已被分配 转换为视图对象
        List<MenuVO> menuVOList = menuList.stream().map(menu -> {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(menu, menuVO);
            //判断菜单是否已经分配到角色
            menuVO.setSelect(roleMenuIds.contains(menuVO.getId()));
            return menuVO;
        }).collect(Collectors.toList());

        // 转化为树对象并返回
        menuVOList = MenuHelper.bulidTree(menuVOList);
        return menuVOList;
    }

    /**
     * 分配权限
     * @param assignMenuDTO
     */
    @Override
    public void doAssign(AssignMenuDTO assignMenuDTO) {
        //删除已分配的权限
        int roleId = this.roleMenuMapper.delete(new QueryWrapper<RoleMenu>().eq("role_id", assignMenuDTO.getRoleId()));

        //批量插入Id
        roleMenuMapper.insertBatch(assignMenuDTO);

    }
}
